compose(List, Comp) :- compose(List, [], Comp).

compose([], Comp, Comp).

compose(List, CompSoFar, Comp) :- 
    member(E, List),
    removeValue(E, List, [], Rest),
    compose(Rest, [E|CompSoFar], Comp).

removeValue(_,    [], RestSoFar, Rest) :- reverse(RestSoFar, Rest), !.

removeValue(E, [E|T], RestSoFar, Rest) :- removeValue(E, T, RestSoFar, Rest), !.

removeValue(E, [H|T], RestSoFar, Rest) :- removeValue(E, T, [H|RestSoFar], Rest).

plusall(List, Result) :- iterate(add, List, 0, [], Result).
minusall(List, Result) :- iterate(minus, List, 0, [], Result).

iterate(_, [], _, ResultSoFar, Result) :- reverse(ResultSoFar, Result). 

iterate(Operator, [H|T], Count, ResultSoFar, Result) :- 
    NewCount is Count + 1,
    operate(Operator, H, Count, E),
    iterate(Operator, T, NewCount, [E|ResultSoFar], Result).  

operate(add, V1, V2, Result) :- Result is V1 + V2.
operate(minus, V1, V2, Result) :- Result is V1 - V2.

noDuplicate([]).
noDuplicate([H|T]) :- not(member(H, T)), noDuplicate(T).

anwser(List) :- compose(List, [], Comp), plusall(Comp, Result1), noDuplicate(Result1), minusall(Comp, Result2), noDuplicate(Result2), writeln(Comp). 


